import { defineComponent, ref } from 'vue'
import classes from './Controls.module.css'
import { setElStylePos } from '../utils'

// 辅助线
export default defineComponent(
  (props, { expose }) => {
    const leftRef = ref()
    const rightRef = ref()
    const topRef = ref()
    const bottomRef = ref()
    const distance = 5 // 吸附距离

    const hideGuides = () => {
      leftRef.value.style.visibility =
        rightRef.value.style.visibility =
        topRef.value.style.visibility =
        bottomRef.value.style.visibility =
          'hidden'

      leftRef.value.style.left =
        rightRef.value.style.left =
        topRef.value.style.top =
        bottomRef.value.style.top =
          '0'
    }

    const showGuides = (targetNode) => {
      if (!(targetNode && leftRef.value && rightRef.value && topRef.value && bottomRef.value))
        return

      hideGuides()

      const targetEl: HTMLElement = targetNode.elRef.value
      const elements = props.page
        .getAllNodes()
        .filter((node: any) => !node.isNPage && node !== targetNode)
        .map((node: any) => node.elRef.value)

      const { left, right, top, bottom, width, height } = targetEl.getBoundingClientRect()

      for (let i = 0, l = elements.length; i < l; i++) {
        const el = elements[i]
        if (!el) continue

        const {
          left: eLeft,
          right: eRight,
          top: eTop,
          bottom: eBottom
        } = el.getBoundingClientRect()

        let posNum,
          pageEl = props.page.elRef.value
        if (
          (posNum =
            (Math.abs(eLeft - left) <= distance && eLeft) ||
            (Math.abs(eRight - left) <= distance && eRight))
        ) {
          leftRef.value.style.visibility = 'visible'
          setElStylePos(leftRef.value, posNum, 'left', pageEl)
          setElStylePos(targetNode.elRef.value, posNum, 'left', pageEl)
        }
        if (
          (posNum =
            (Math.abs(eLeft - right) <= distance && eLeft) ||
            (Math.abs(eRight - right) <= distance && eRight))
        ) {
          rightRef.value.style.visibility = 'visible'
          setElStylePos(rightRef.value, posNum, 'left', pageEl)
          setElStylePos(targetNode.elRef.value, posNum - width, 'left', pageEl)
        }
        if (
          (posNum =
            (Math.abs(eTop - top) <= distance && eTop) ||
            (Math.abs(eBottom - top) <= distance && eBottom))
        ) {
          topRef.value.style.visibility = 'visible'
          setElStylePos(topRef.value, posNum, 'top', pageEl)

          setElStylePos(targetNode.elRef.value, posNum, 'top', pageEl)
        }
        if (
          (posNum =
            (Math.abs(eTop - bottom) <= distance && eTop) ||
            (Math.abs(eBottom - bottom) <= distance && eBottom))
        ) {
          bottomRef.value.style.visibility = 'visible'
          setElStylePos(bottomRef.value, posNum, 'top', pageEl)
          setElStylePos(targetNode.elRef.value, posNum - height, 'top', pageEl)
        }
      }

      targetNode.updateStyle()
    }

    expose({
      hideGuides,
      showGuides
    })

    return () => (
      <>
        <div ref={leftRef} class={`${classes['guide']} ${classes['guide-vertical']}`}></div>
        <div ref={rightRef} class={`${classes['guide']} ${classes['guide-vertical']}`}></div>
        <div ref={topRef} class={`${classes['guide']} ${classes['guide-horizontal']}`}></div>
        <div ref={bottomRef} class={`${classes['guide']} ${classes['guide-horizontal']}`}></div>
      </>
    )
  },
  {
    props: {
      page: {
        type: Object
      }
    }
  }
)
